#!/user/bin/env python
# -*- coding: utf-8 -*-
"""
Author: Sjy
LastEditTime: 2024-12-17 11:24:26
Description: 菜单和dock 命令集合
"""

__all__ = []

import gui.controls.envs as envs

try:
    from .uis import (
        ImportMainModel,
        ImportSubmodel,
        ImportAnalysisModel,
        DlgLowShowResult,
    )
except:
    print("uis 模块异常")

try:
    from .params_model import (
        DlgParamsModeling,
        DlgLoadBoundary,
        DlgMeshPartition,
        DlgPostProcessing,
        DlgCompositePly,
        DlgAdhesiveLayer,
        DlgHoneycombCore,
        DlgMaterialSetting,
        DlgOptimization,
        DlgMaterialLibrary,
        DlgLifeAnalysis,
        DlgLifeAnalysisDFR,
        DlgBaseInfo,
    )
except:
    print("params_model 模块异常")

try:
    from .actions import Actions
except:
    print("actions 模块异常")

import os
import json


class Pops:
    def import_main_model() -> None:
        """导入模型
        Args:
            None
        Returns:
            None
        """
        ImportMainModel()

    def import_submodel() -> None:
        """导入计算模型"""
        ImportSubmodel()

    def show_dlg(flag) -> None:
        """显示对话框
        Args:
            flag : 对话框标识
        Returns:
            None
        """
        py3d = envs.GL.get_value("py3d")

        dlg = None

        cfgIndex = {}
        with open("config/sys/index.json", "r", encoding="utf-8") as file:
            cfgIndex = json.load(file) or {}
        theme = cfgIndex.get("theme", "dark")  # dark or light
        qss = "styles/dlg.qss"
        if theme == "light":
            qss = "styles/dlg_light.qss"

        if flag == "meshPartition":
            dlgMeshPartition = DlgMeshPartition.show(py3d)
            if dlgMeshPartition:
                dlgMeshPartition.meshPartition_save_signal.connect(
                    lambda data: Pops.meshPartition_save_signal(data)
                )
        elif flag == "loadBoundary":
            dlgLoadBoundary = DlgLoadBoundary.show(py3d)
            if dlgLoadBoundary:
                dlgLoadBoundary.loadBoundary_save_signal.connect(
                    lambda data: Pops.loadBoundary_save_signal(data)
                )
        elif flag == "optimizationMethod":
            dlgOptimization = DlgOptimization.show(py3d)
            if dlgOptimization:
                dlgOptimization.optimization_save_signal.connect(
                    lambda data: Pops.optimization_save_signal(data)
                )
        elif flag == "postProcessing":
            dlgPostProcessing = DlgPostProcessing.show(py3d)
            if dlgPostProcessing:
                dlgPostProcessing.postProcessing_save_signal.connect(
                    lambda data: Pops.postProcessing_save_signal(data)
                )

        elif flag == "materialSetting":
            dlgMaterialSetting = DlgMaterialSetting.show(py3d)
            if dlgMaterialSetting:
                dlgMaterialSetting.materialSetting_save_signal.connect(
                    lambda data: Pops.materialSetting_save_signal(data)
                )

            dlgMaterialSetting.setStyleSheet(open(qss, "r").read())
        # elif flag == "compositePly":
        #     dlgCompositePly = DlgCompositePly.show(py3d)
        #     if dlgCompositePly:
        #         dlgCompositePly.compositePly_save_signal.connect(lambda data: Pops.compositePly_save_signal(data))
        # elif flag == "adhesiveLayer":
        #     dlgAdhesiveLayer = DlgAdhesiveLayer.show(py3d)
        #     if dlgAdhesiveLayer:
        #         dlgAdhesiveLayer.adhesiveLayer_save_signal.connect(lambda data: Pops.adhesiveLayer_save_signal(data))
        # elif flag == "honeycombCore":
        #     dlgHoneycombCore = DlgHoneycombCore.show(py3d)
        #     if dlgHoneycombCore:
        #         dlgHoneycombCore.honeycombCore_save_signal.connect(lambda data: Pops.honeycombCore_save_signal(data))
        # if flag =="materiasingle": # 单个修改接口
        #     dlgMaterialsingle = DlgMaterialsingle.show(parent=py3d,materialType="蜂窝芯子",materialName="R1")
        #     if dlgMaterialsingle:
        #         dlgMaterialsingle.setwindowTitle('')
        #         dlgMaterialsingle.materialsingle_save_signal.connect(lambda data: Pops.materialsingle_save_signal(data))
        elif flag == "paramsModeling":
            dlgParamsModeling = DlgParamsModeling.show(py3d)
            if dlgParamsModeling:
                dlgParamsModeling.paramsModeling_save_signal.connect(
                    lambda data: Pops.paramsModeling_save_signal(data)
                )
        # 低周疲劳约束 ==================================================================================================
        elif flag == "analysisModeling":
            dlg = ImportAnalysisModel(parent=py3d)
            if dlg:
                dlg.sigOnSave.connect(
                    lambda data: Pops.lower_save_signal("分析模型", data)
                )
        elif flag == "lifeAnalysis":
            dlg = DlgLifeAnalysis.show(py3d)
            if dlg:
                dlg.lifeAnalysis_save_signal.connect(
                    lambda data: Pops.lower_save_signal("寿命分析", data)
                )
                # dlgLifeAnalysis.lifeAnalysis_save_signal.connect(lambda data: Pops.lifeAnalysis_save_signal(data))
        elif flag == "materialsProperties":
            dlg = DlgMaterialLibrary.show(py3d)
            if dlg:
                dlg.materialLibrary_save_signal.connect(
                    lambda data: Pops.lower_save_signal("材料属性", data)
                )
        elif flag == "lowShowResult":
            DlgLowShowResult()

        # DFR 疲劳分析 ==================================================================================================
        elif flag == "dfr_analysis":
            dlgLifeAnalysisDFR = DlgLifeAnalysisDFR.show(py3d)
            if dlgLifeAnalysisDFR:
                dlgLifeAnalysisDFR.lifeAnalysisDFR_save_signal.connect(
                    lambda data: Pops.dlgLifeAnalysisDFR_save_signal(data)
                )

            # dlgLifeAnalysis.lifeAnalysisDFR_save_signal.connect(lambda data: Pops.lifeAnalysisDFR_save_signal(data))

        elif flag == "analysisSetting":
            """极限受载分析-分析设置,
            注意分析设置是根据基础信息 设置的材料类型决定弹出什么界面,当前阶段只有低周疲劳, TODO: 后续需要根据材料类型决定弹出什么界面
            """
            # data = None
            # if data.get("材料类型") == "金属材料破坏":
            #     pass
            # elif data.get("材料类型") == "金属材料低周疲劳":
            #     dlg = ImportAnalysisModel(parent = py3d)
            #     if dlg:
            #         dlg.sigOnSave.connect(lambda data: Pops.lower_save_signal("分析模型", data))
            # elif data.get("材料类型") == "金属材料高周疲劳":
            #     pass
            # elif data.get("材料类型") == "复合材料破坏":
            #     pass
            # dlg = ImportAnalysisModel(parent = py3d)
            # if dlg:
            #     dlg.sigOnSave.connect(lambda data: Pops.lower_save_signal("分析模型", data))
            dlg = DlgLifeAnalysis.show(py3d)
            if dlg:
                dlg.lifeAnalysis_save_signal.connect(
                    lambda data: Pops.lower_save_signal("寿命分析", data)
                )

        elif flag == "loadCalculation":
            """极限受载分析-载荷计算"""
            dlg = DlgLowShowResult(py3d)
            if dlg:
                dlg.sigOnSave.connect(
                    lambda data: Pops.lower_save_signal("分析模型", data)
                )

    def paramsModeling_save_signal(data) -> None:
        """保存参数建模数据
        Args:
            data: 参数建模数据
        Returns:
            None
        """
        # print("paramsModeling_save_signal=", data)
        delKeys = []
        if data.get("损伤类型") != "贯穿式损伤":
            delKeys = [
                "额外挖除尺寸",
                "下铺层修补胶层层数",
                "下铺层修补层层数",
                "下铺层修补层",
            ]
        if not (
            data.get("损伤类型") == "蜂窝芯子损伤"
            or data.get("损伤类型") == "贯穿式损伤"
        ):
            delKeys.append("蜂窝芯子修补层")
        Actions.save_data(data, delKeys=delKeys)
        # TODO: 运行完成后要根据异步返回的信息更新显示的模型

    def meshPartition_save_signal(data: dict = {}) -> None:
        # print("meshPartition_save_signal", data)
        Actions.save_data(data)

    def loadBoundary_save_signal(data: dict = {}) -> None:
        # print("loadBoundary_save_signal", data)
        Actions.save_data(data)

    def postProcessing_save_signal(data: dict = {}) -> None:
        # print("postProcessing_save_signal", data)
        Actions.save_data(data)

    def optimization_save_signal(data: dict = {}) -> None:
        # print("optimization_save_signal=", data)

        Actions.save_data(data)

    def materialSetting_save_signal(data: dict = {}) -> None:
        """材料设置
        {
        '上铺层': # 上铺层
            [{'material': {'E/Enn': '1.0', 'G1/Enn': '2.0', 'G2/Enn': '3.0', '名称': 'jc1'}, 'Angle': 2.0}, {'material': {'E/Enn': '2.0', 'G1/Enn': '3.0', 'G2/Enn': '4.0', '名称': 'jc2'}, 'Angle': 2.0}],
        '下铺层': # 下铺层
            [{'material': {'Es': '4.0', 'Gs': '5.0', '名称': 'FW2', '壁厚t': '1.0', '密度ρ': '3.0', '边长l': '2.0'}, 'Angle': 1.0}, {'material': {'Es': '4.0', 'Gs': '5.0', '名称': 'FW1', '壁厚t': '1.0', '密度ρ': '34.0', '边长l': '2.0'}, 'Angle': 2.0}],
        '上铺层修补层': # 上铺层修补层
            [{'material': {'E1': '1.0', 'E2': '2.0', 'G12': '4.0', 'G13': '5.0', 'G23': '6.0', 'Nu12': '3.0', '名称': 'test1'}, 'Angle': 2.0}, {'material': {'Es': '4.0', 'Gs': '5.0', '名称': 'FW1', '壁厚t': '1.0', '密度ρ': '34.0', '边长l': '2.0'}, 'Angle': 3.0}, {'material': {'E/Enn': '1.0', 'G1/Enn': '2.0', 'G2/Enn': '3.0', '名称': 'jc1'}, 'Angle': 4.0}],
        '下铺层修补层':  # 下铺层修补层
            [{'material': {'E1': '1.0', 'E2': '2.0', 'G12': '4.0', 'G13': '5.0', 'G23': '6.0', 'Nu12': '3.0', '名称': 'test1'}, 'Angle': 3.0}, {'material': {'Es': '4.0', 'Gs': '5.0', '名称': 'FW1', '壁厚t': '1.0', '密度ρ': '34.0', '边长l': '2.0'}, 'Angle': 4.0}, {'material': {'E/Enn': '1.0', 'G1/Enn': '2.0', 'G2/Enn': '3.0', '名称': 'jc1'}, 'Angle': 5.0}],
        '下铺层填充层': 下铺层 填充层
            [{'material': {'E1': '1.0', 'E2': '2.0', 'G12': '4.0', 'G13': '5.0', 'G23': '6.0', 'Nu12': '3.0', '名称': 'test1'}, 'Angle': 2.0}, {'material': {'E1': '5.0', 'E2': '5.0', 'G12': '2.0', 'G13': '3.0', 'G23': '4.0', 'Nu12': '1.0', '名称': 'test3'}, 'Angle': 3.0}],
        '蜂窝芯子材料': # 蜂窝芯子材料
            {'Es': '4.0', 'Gs': '5.0', '名称': 'FW1', '壁厚t': '1.0', '密度ρ': '34.0', '边长l': '2.0'}
        '蜂窝芯子修补层': # 蜂窝芯子修补层
            {'E/Enn': '1.0', 'G1/Enn': '2.0', 'G2/Enn': '3.0', '名称': 'jc1'}
        }

        Args:
            data: 材料设置数据
        Returns:
            None
        Description:
            1. 先获取参数化建模数据
            2. 将材料设置中的数据补全到对应参数化建模数据中的对应位置
        """
        # print("materialSetting_save_signal=", data)
        inputData = Actions.get_data() or {}
        # 批量更新 层数据
        for key in ["上铺层", "上铺层修补层", "下铺层", "下铺层修补层"]:
            inputData[key] = Pops._update_materials(data, inputData, key)

        key = "蜂窝芯子材料"
        honeycombCoreInput = inputData.get(key, {})
        Pops.remove_item_keys(honeycombCoreInput)
        honeycombCoreInput.update(data.get(key, {}))
        inputData[key] = honeycombCoreInput

        # 更新 蜂窝芯子修补层 注意 蜂窝芯子损伤/贯穿式损伤时启用
        curType = inputData.get("损伤类型")
        key = "蜂窝芯子修补层"  # 目前只有一层
        if curType == "贯穿式损伤" or curType == "蜂窝芯子损伤":
            # print("===========================================================")
            honeycombCoreRepairInput = inputData.get(key, [])  # 列表只有一层
            if len(honeycombCoreRepairInput) == 0:
                honeycombCoreRepairInput.append({})
            Pops.remove_item_keys(honeycombCoreRepairInput[0])
            honeycombCoreRepairInput[0].update(data.get(key, {}))
            inputData[key] = honeycombCoreRepairInput
            # print("honeycombCoreRepairInput=", honeycombCoreRepairInput)
        elif key in inputData:
            inputData.pop(key)
        key = "下铺层填充层"
        inputData[key] = [
            {**item.get("材料"), "铺层角度": item.get("铺层角度")}
            for item in data.get(key, [])
        ]
        Actions.save_data(inputData) or {}

    def _update_materials(data, inputData, key):
        savedItems = inputData.get(key, [])
        curItems = data.get(key, [])
        # 上铺层、下铺层、上铺层修补层、下铺层修补层 这些的层数必须是一一对应的关系
        if len(savedItems) == len(curItems):
            for index, item in enumerate(savedItems):
                Pops.remove_item_keys(item)
                curItem = curItems[index]
                item.update(curItem.get("材料"))
                item.update({"铺层角度": curItem.get("铺层角度")})
            return savedItems
        else:
            print(f"{key} : 数据不匹配")

    def remove_item_keys(item: dict = {}):
        materialType = item.get("材料类型")
        if materialType:
            # 如果材料类型存在 则检查属于哪种类型 需要删除原有的然后更新现在的
            keys = Pops.get_materil_keys(materialType)
            # 根据列表keys 中的key 批量移除 item中的数据
            for key in keys:
                if key in item:
                    item.pop(key)

    def get_materil_keys(materialType):
        # 取key 即可
        if materialType == "蜂窝芯子":
            return {
                "Es": "4.0",
                "Gs": "5.0",
                "材料名称": "FW1",
                "壁厚t": "1.0",
                "密度ρ": "34.0",
                "边长l": "2.0",
            }.keys()
        elif materialType == "胶层":
            return {
                "E/Enn": "1.0",
                "G1/Enn": "2.0",
                "G2/Enn": "3.0",
                "材料名称": "jc1",
            }.keys()
        elif materialType == "复合材料单层板":
            return {
                "E1": "1.0",
                "E2": "2.0",
                "G12": "4.0",
                "G13": "5.0",
                "G23": "6.0",
                "Nu12": "3.0",
                "材料名称": "test1",
            }.keys()

    def compositePly_save_signal(data: dict = {}) -> None:
        # print("复合材料单层板=", data)
        """材料保存目前不需要后续处理"""

    def adhesiveLayer_save_signal(data: dict = {}) -> None:
        # print("蜂窝芯子=", data)
        """材料保存目前不需要后续处理"""

    def honeycombCore_save_signal(data: dict = {}) -> None:
        # print("胶层=", data)
        """材料保存目前不需要后续处理"""

    def dlgLifeAnalysisDFR_save_signal(data: dict = {}) -> None:
        """保存疲劳分析数据"""
        # print("疲劳分析数据=", data)
        path = "data/ipimas"
        if not os.path.exists(path):
            os.makedirs(path)
        file = f"{path}/input_dfr.json"
        Actions.save_data(data, file, update=False)

    def lower_save_signal(key, data: dict = {}) -> None:
        """保存低周疲劳约束 相关数据"""
        path = "data/ipimas"
        if not os.path.exists(path):
            os.makedirs(path)
        file = f"{path}/input_lower.json"
        oldData = Actions.get_data(file) or {}
        oldData[key] = data
        Actions.save_data(oldData, file, update=False)
        # 导入分析模型时 如果点击确定直接弹出 基本信息界面

    def show_basic_info_dlg(
        data: dict = {}, failureAreas: list = [], failureTypes: list = []
    ):
        """显示基本信息界面

        Args:
            data (dict, optional): 分析模型数据. Defaults to {}.
            failureAreas (list, optional): 失效区域. Defaults to [].
            failureTypes (list, optional): 失效类型. Defaults to [].
        """
        py3d = envs.GL.get_value("py3d")
        dlgBaseInfo = DlgBaseInfo.show(py3d)
        if dlgBaseInfo:
            pass
            # dlgBaseInfo.baseInfo_save_signal.connect(
            #     # lambda data: Pops.baseInfo_save_signal(data)
            # )

            # print("failureAreas=", failureAreas)
            # print("failureTypesOpt=", failureTypes)

            dlgBaseInfo.init(
                data, analysisAreaOpt=failureAreas, failureTypesOpt=failureTypes
            )

    def import_analysis_model(data: dict = {}, title: str = "导入模型"):
        py3d = envs.GL.get_value("py3d")
        dlg = ImportAnalysisModel(parent=py3d)

        data = Actions.get_data("data/ipimas/input_analysis_model.json") or {}
        dlg.setWindowTitle("导入分析模型")
        if dlg:
            dlg.init(data)
            dlg.sigOnSave.connect(lambda data: Pops.import_extreme_load_analysis(data))
            dlg.sigOnRunParamsModeling.connect(
                lambda data: Pops.run_params_modeling(data)
            )

    def run_params_modeling(data: dict = {}):
        """运行参数建模"""
        Pops.show_dlg(flag="paramsModeling")

    def import_extreme_load_analysis(data: dict = {}):
        """导入极限受载分析"""
        # 获取 极限受载分析 保存的数据
        Pops.show_basic_info_dlg(
            data,
            failureAreas=[
                {"title": "set-1, solid", "value": "set-1, solid"},
                {"title": "set-2, shell", "value": "set-2, shell"},
            ],
            failureTypes=[
                {"title": "金属材料破坏", "value": "金属材料破坏"},
                {"title": "金属材料低周疲劳", "value": "金属材料低周疲劳"},
                {"title": "金属材料高周疲劳", "value": "金属材料高周疲劳"},
                {"title": "复合材料破坏", "value": "复合材料破坏"},
            ],
        )
